package org.common.mongo;

import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.common.mongo.collection.BaseCollection;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.List;


/**
 * mongo服务
 */
@Slf4j
@Component
public class MongoService {

    private MongoContext mongoContext;

    /**
     * 初始化mongo服务
     */
    public void initMongoService(String mongoUrl, String user, String password, String dbName) {
        MongoContext mongoContext = new MongoContext();
        mongoContext.initMongoContext(mongoUrl, user, password, dbName);
        this.mongoContext = mongoContext;
        log.info("mongo service ok!");
    }

    public MongoContext getMongoContext() {
        return mongoContext;
    }

    /**
     * 插入数据
     */
    public <T extends BaseCollection> boolean insert(T obj) {
        mongoContext.getMongoTemplate().insert(obj);
        return true;
    }

    /**
     * 查询数据
     */
    public <T extends BaseCollection> T findById(Object id, Class<T> clz) {
        return mongoContext.getMongoTemplate().findById(id, clz);
    }
    public <T extends BaseCollection> T findOneByQuery(Criteria criteria, Class<T> clz) {
        Query query = Query.query(criteria);
        return mongoContext.getMongoTemplate().findOne(query, clz);
    }
    public <T extends BaseCollection> List<T> findMany(Criteria criteria, Class<T> clz) {
        Query query = Query.query(criteria);
        return mongoContext.getMongoTemplate().find(query, clz);
    }

    /**
     * 删除数据
     */
    public void removeById(Object id, String collectionName) {
        Criteria criteria = Criteria.where("_id").is(id);
        DeleteResult result = mongoContext.getMongoTemplate().remove(Query.query(criteria), collectionName);
        long deletedCount = result.getDeletedCount();
        if (deletedCount == 0) {
            log.warn("removeById not find collection. collectionName = {}, _id = {}", collectionName, id);
        }
    }

    /**
     * 改
     */
    public <T extends BaseCollection> void replaceCollection(T collection) {
        Criteria criteria = Criteria.where("_id").is(collection.getId());
        UpdateResult result = mongoContext.getMongoTemplate().replace(Query.query(criteria), collection);
        long modifiedCount = result.getModifiedCount();
        if (modifiedCount == 0) {
            log.warn("removeById not find collection. collectionName = {}, _id = {}", collection.getClass().getSimpleName(), collection.getId());
        }
    }

    /**
     * 更新
     */
    public <T extends BaseCollection> void updateCollection(T collection, Query query, Update update) {
        UpdateResult result = mongoContext.getMongoTemplate().updateFirst(query, update, collection.getClass());
        if (result.getModifiedCount() == 0) {
            log.warn("updateCollection not find collection. collectionName = {}, _id = {}, query = {}, update = {}", collection.getClass().getSimpleName(), collection.getId(), query, update);
        }
    }
}
